#ifndef BASE_SYSTEM_LOG_LOGGER_INCLUDE_LOG_FORMAT_H
#define BASE_SYSTEM_LOG_LOGGER_INCLUDE_LOG_FORMAT_H

#include <memory>
#include <vector>
#include "log_formatter.h"

namespace Base {
namespace SystemLog {
class LogFormat {
public:
    LogFormat() = default;

    void AddFormatter(std::shared_ptr<LogFormatter> formatter) {
        formatters_.emplace_back(std::move(formatter));
    }

    void Format(LogStream &stream) const {
        for (const auto &formatter : formatters_) {
            formatter->Format(stream);
            if (formatter.get() != formatters_.back().get()) {
                stream << " ";
            }
        }
    }

    static LogFormat Default() {
        LogFormat format;
        format.AddFormatter(std::make_shared<TimeFormatter>());
        format.AddFormatter(std::make_shared<LevelFormatter>());
        format.AddFormatter(std::make_shared<ThreadIdFormatter>());
        format.AddFormatter(std::make_shared<FileFormatter>());
        format.AddFormatter(std::make_shared<MessageFormatter>());
        return format;
    }

    static LogFormat DefaultWithMilliseconds() {
        LogFormat format;
        format.AddFormatter(std::make_shared<TimeFormatterWithMilliseconds>());
        format.AddFormatter(std::make_shared<LevelFormatter>());
        format.AddFormatter(std::make_shared<ThreadIdFormatter>());
        format.AddFormatter(std::make_shared<FileFormatter>());
        format.AddFormatter(std::make_shared<MessageFormatter>());
        return format;
    }

    static LogFormat Simple() {
        LogFormat format;
        format.AddFormatter(std::make_shared<TimeFormatter>());
        format.AddFormatter(std::make_shared<LevelFormatter>());
        format.AddFormatter(std::make_shared<MessageFormatter>());
        return format;
    }

    static LogFormat SimpleWithMilliseconds() {
        LogFormat format;
        format.AddFormatter(std::make_shared<TimeFormatterWithMilliseconds>());
        format.AddFormatter(std::make_shared<LevelFormatter>());
        format.AddFormatter(std::make_shared<MessageFormatter>());
        return format;
    }
private:
    std::vector<std::shared_ptr<LogFormatter>> formatters_;
};
} // namespace SystemLog
} // namespace Base

#endif // BASE_SYSTEM_LOG_LOGGER_INCLUDE_LOG_FORMAT_H